﻿/**************************************************************
*作者：Leon
*创建时间：2022/4/7 19:00:00
**************************************************************/
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;

namespace Lad.DrawProject.Controls;

abstract class CanvasActionBase : BaseAction
{
    private IDiagramServiceProvider? serviceProvider;

    public IDiagramServiceProvider ServiceProvider
    {
        get{ return serviceProvider ??= DiagramServicesProvider.Instance;}
    }
}

/// <summary>
/// 缩放命令
/// </summary>
internal class ZommAction : CanvasActionBase
{
    private readonly double newValue;
    private readonly double oldValue;
    private readonly ScrollViewCanvasViewModel viewModel;
    private const double minmium = 0.01;
    private const double maxminum = 100;
    public ZommAction(ScrollViewCanvasViewModel viewModel, double value)
    {
        var zoomValue = viewModel.ZoomValue;
        //newValue = zoomValue + (value > 0 ? 0.1 : -0.1);
        newValue = value > 0 ? zoomValue * 1.08 : zoomValue / 1.08;
        newValue = newValue < minmium ? minmium :
            (newValue > maxminum ? maxminum : newValue);
        oldValue = viewModel.ZoomValue;
        
        this.viewModel = viewModel;
    }

    public override void Do()
    {
        viewModel.ZoomValue=newValue;
    }

    public override string GetName()
    {
        return "Zomm Action";
    }

    public override void Undo()
    {
        viewModel.ZoomValue=oldValue;
    }
}


public class PropertyChangedAction<T> : BaseAction, IAction
{
    private readonly object sender;
    private readonly string? propertyName;
    private readonly T? oldValue;
    private readonly T? newValue;
    private static readonly BindingFlags BindingFlags =
        BindingFlags.NonPublic
        | BindingFlags.Instance
        | BindingFlags.Public
        | BindingFlags.Static;
    public PropertyChangedAction(object sender, T? oldValue, T? newValue, [CallerMemberName] string? propertyName = default)
    {
        this.sender = sender;
        this.propertyName = propertyName;
        this.oldValue = oldValue;
        this.newValue = newValue;
    }
    public PropertyChangedAction(object sender)
    {
        this.sender = sender;
    }

    public override void Do()
    {
        if (newValue?.Equals(oldValue) == true)
            return;
        if (!string.IsNullOrEmpty(propertyName))
            sender.GetType().GetProperty(propertyName, BindingFlags)?.SetValue(sender, newValue);
    }

    public override string GetName()
    {
        return $"{sender.GetType().Name} Proptry {propertyName} Change Action";
    }

    public override void Undo()
    {
        if (newValue?.Equals(oldValue) == true)
            return;
        if (!string.IsNullOrEmpty(propertyName))
            sender.GetType().GetProperty(propertyName, BindingFlags)?.SetValue(sender, oldValue);
    }
}
